/************************************************************
	File:		Enemy.cpp
	Author:		Mitchel Mishiev, Keisuke Miyazaki
	Purpose:	CEnemy class controls the enemies
************************************************************/
#include "Enemy.h"
#include <ctime>

#include "../GameStates/GamePlayState.h"

#include "../Messages and Events/CreateKunaiMessage.h"
#include "Kunai.h"
#include "../Messages and Events/DestroyEntityMessage.h"

#include "../../SGD Wrappers/CSGD_Direct3D.h"
#include "../../SGD Wrappers/CSGD_DirectInput.h"
#include "../../SGD Wrappers/CSGD_TextureManager.h"
#include "../../SGD Wrappers/CSGD_XAudio2.h"
#include "../../SGD Wrappers/SGD_String.h"
#include "../../SGD Wrappers/CSGD_EventSystem.h"
#include "../../SGD Wrappers/CSGD_MessageSystem.h"

#define TM CSGD_TextureManager::GetInstance()
#define D3 CSGD_Direct3D::GetInstance()
#define XA CSGD_XAudio2::GetInstance()

#define MoveRate 0.05f
#define PatrolTimer 0.43f
#define SoundTimer 0.12f

#define DamageTimer 0.1f

#define Shot_Delay	0.75f;
#define Shot_Mod	6
#define PI D3DX_PI

#define Red					D3DCOLOR_ARGB( 255, 255, 0,	0	)

CEnemy::CEnemy(void)
{
	m_eType = ENT_ENEMY;

	SetHealth( 50 );
	SetAlignmentID( 1 );

	SetWidth( 50 );
	SetHeight( 50 );

	m_nSouls	=	10;
	m_nDamage	=	5;
	m_nAIState	=	0;
	
	m_nImageID		=	TM->LoadTexture( _T( "resource/graphics/Entities/TEST_Enemy.png" ) );
	m_nOuchSfxID	=	XA->SFXLoadSound(  _T( "resource/sounds/SFX_Ouch.wav" ) );
	m_nRunSfxID		=	XA->SFXLoadSound(  _T( "resource/sounds/SFX_Running.wav" ) );
	m_nHeySfxID		=	XA->SFXLoadSound( _T(  "resource/sounds/SFX_Hey.wav" ) );

	m_fSoundtimer	= SoundTimer;
	m_fDmgTimer		= 0.0f;
	m_bIsHit		= false;
	m_fShootTimer	= Shot_Delay;

	m_fPatrolTimer = 0.0f;
	m_nPatrolDirection = dDown;

	m_bIsDead = false;
	m_fDeadtimer = 2.0f;
}

CEnemy::~CEnemy(void)
{
	TM->UnloadTexture( m_nImageID );
	XA->SFXUnloadSound( m_nOuchSfxID );
	XA->SFXUnloadSound( m_nRunSfxID );
	XA->SFXUnloadSound( m_nHeySfxID );

	m_nImageID		= -1;
	m_nOuchSfxID	= -1;
	m_nRunSfxID		= -1;
	m_nHeySfxID		= -1;
}

void CEnemy::Update( float fElapsedTime )
{
	if ( GetAlive() )
	{
		if ( m_fShootTimer > 0.0f )
			m_fShootTimer -= fElapsedTime;

		if ( m_fSoundtimer <= 0 )
			m_fSoundtimer = SoundTimer;

		if ( m_fDmgTimer > 0.0f && m_bIsHit == true )
			m_fDmgTimer -= fElapsedTime;

		if ( m_fDmgTimer <= 0.0f )
		{
			m_fDmgTimer = 0.0f;
			m_bIsHit = false;
		}

		m_fSoundtimer -= fElapsedTime;

		TestPatrol( m_nPatrolDirection );

		m_fPatrolTimer += fElapsedTime;


		if ( m_fPatrolTimer >= PatrolTimer )
		{
			m_nPatrolDirection = ( rand()  % 5);

			m_fPatrolTimer = 0.0f;
		}

		StayInBoundaries();
	}
	else
	{
		m_fDeadtimer -= fElapsedTime;
		if ( m_fDeadtimer <= 0.0f )
		{
			CDestroyEntityMessage* pMsg = new CDestroyEntityMessage( this );

			CSGD_MessageSystem::GetInstance()->SendMsg( pMsg );
			pMsg = nullptr;
		}
	}

}
void CEnemy::Render( void )
{
	CGamePlayState*	pGPS	= CGamePlayState::GetInstance();

	RECT rEnemy;

	switch ( GetAlive() )
	{
	case true:
		{
			rEnemy.left		=	0;
			rEnemy.top		=	0;
			rEnemy.right	=	47;
			rEnemy.bottom	=	50;
		}
		break;

	case false:
		{
			rEnemy.left		=	49;
			rEnemy.top		=	0;
			rEnemy.right	=	99;
			rEnemy.bottom	=	50;
		}
		break;
	}

	switch ( GetAlive() )
	{
	case true:
		{
			if ( m_bIsHit == false )
			{
				TM->Draw( m_nImageID, 
					(float) ( GetPosX() - (GetWidth() * 0.5f ) ) - pGPS->GetCameraX(),  
					(float) ( GetPosY() - (GetHeight() * 0.5f ) ) - pGPS->GetCameraY(),
					1.0f, 
					1.0f,
					&rEnemy );
			}

			if ( m_bIsHit == true )
			{
				RECT rHit;
				rHit.left		=	(float) ( GetPosX() - (GetWidth() * 0.5f ) ) - pGPS->GetCameraX();
				rHit.top		=	(float) ( GetPosY() - (GetHeight() * 0.5f )) - pGPS->GetCameraY();
				rHit.right		=	(float) ( GetPosX() + (GetWidth() * 0.5f ) ) - pGPS->GetCameraX();
				rHit.bottom		=	(float) ( GetPosY() + (GetHeight() * 0.5f ) ) - pGPS->GetCameraY();

				D3->DrawRect( rHit, Red );
			}
		}
		break;
	case false:
		{
			TM->Draw( m_nImageID, 
				(float) ( GetPosX() - (GetWidth() * 0.5f ) ) - pGPS->GetCameraX(),  
				(float) ( GetPosY() - (GetHeight() * 0.5f ) ) - pGPS->GetCameraY(),
				1.0f, 
				1.0f,
				&rEnemy ); 
		}
		break;
	}
}

void CEnemy::HandleCollision( const IEntity* pOther )
{
	if ( GetAlive() )
	{
		switch ( pOther->GetType() )
		{
		case ENT_KUNAI:
			{
				XA->SFXPlaySound( m_nOuchSfxID );

				m_bIsHit = true;
				m_fDmgTimer = DamageTimer;
				SetHealth( GetHealth() - 10 );

				if ( GetHealth() <= 0 )
				{
					SetAlive( false );

					int nKills = 1;
					CSGD_EventSystem::GetInstance()->SendEventNow(
						"INCREASE_KILLCOUNT", &nKills, nullptr, this );
				}
			}
			break;
		case ENT_PLAYER:
			{
				
			}
			break;
		}
	}
}

void CEnemy::SwitchAI()
{

}

void CEnemy::TestPatrol( int PatrolDirection )
{
	switch ( m_nPatrolDirection )
	{
	case dUp:
		{
			SetPosY( GetPosY() - MoveRate );
			if ( m_fSoundtimer <= 0.0f )
			{
				if( XA->SFXIsSoundPlaying( m_nRunSfxID ) == false )
					XA->SFXPlaySound( m_nRunSfxID );

				else if( XA->SFXIsSoundPlaying( m_nRunSfxID ) == true )
					XA->SFXStopSound( m_nRunSfxID );
				
				
				SetDirection( eUp );
				if ( m_fShootTimer <= 0.0f )
				{
					CCreateKunaiMessage* pMsg = new CCreateKunaiMessage(
						1,
						GetPosX(), 
						GetPosY(), GetDirection() );

					CSGD_MessageSystem::GetInstance()->SendMsg( pMsg );
					pMsg = nullptr;

					m_fShootTimer = (rand() % Shot_Mod) * Shot_Delay;
				}
			}
		}
		break;
	case dDown:
		{
			SetPosY( GetPosY() + MoveRate );
			if ( m_fSoundtimer <= 0.0f )
			{
				if( XA->SFXIsSoundPlaying( m_nRunSfxID ) == false )
					XA->SFXPlaySound( m_nRunSfxID );

				else if( XA->SFXIsSoundPlaying( m_nRunSfxID ) == true )
					XA->SFXStopSound( m_nRunSfxID );

				SetDirection( eDown );
				if ( m_fShootTimer <= 0.0f )
				{
					CCreateKunaiMessage* pMsg = new CCreateKunaiMessage(
						1,
						GetPosX(), 
						GetPosY(), GetDirection() );

					CSGD_MessageSystem::GetInstance()->SendMsg( pMsg );
					pMsg = nullptr;

					m_fShootTimer = (rand() % Shot_Mod) * Shot_Delay;
				}
			}
		}
		break;
	case dLeft:
		{
			SetPosX( GetPosX() - MoveRate );
			if ( m_fSoundtimer <= 0.0f )
			{
				if( XA->SFXIsSoundPlaying( m_nRunSfxID ) == false )
					XA->SFXPlaySound( m_nRunSfxID );

				else if( XA->SFXIsSoundPlaying( m_nRunSfxID ) == true )
					XA->SFXStopSound( m_nRunSfxID );

				SetDirection( eLeft );
				if ( m_fShootTimer <= 0.0f )
				{
					CCreateKunaiMessage* pMsg = new CCreateKunaiMessage(
						1,
						GetPosX(), 
						GetPosY(), GetDirection() );

					CSGD_MessageSystem::GetInstance()->SendMsg( pMsg );
					pMsg = nullptr;

					m_fShootTimer = (rand() % Shot_Mod) * Shot_Delay;
				}
			}
		}
		break;
	case dRight:
		{
			SetPosX( GetPosX() + MoveRate );
			if ( m_fSoundtimer <= 0.0f )
			{
				if( XA->SFXIsSoundPlaying( m_nRunSfxID ) == false )
					XA->SFXPlaySound( m_nRunSfxID );

				else if( XA->SFXIsSoundPlaying( m_nRunSfxID ) == true )
					XA->SFXStopSound( m_nRunSfxID );

				SetDirection( eRight );
				if ( m_fShootTimer <= 0.0f )
				{
					CCreateKunaiMessage* pMsg = new CCreateKunaiMessage(
						1,
						GetPosX(), 
						GetPosY(), GetDirection() );

					CSGD_MessageSystem::GetInstance()->SendMsg( pMsg );
					pMsg = nullptr;

					m_fShootTimer = (rand() % Shot_Mod) * Shot_Delay;
				}
			}
		}
		break;
	case dStill:
		{
			if ( m_fSoundtimer <= 0.0f )
			{
				if( XA->SFXIsSoundPlaying( m_nHeySfxID ) == false )
					XA->SFXPlaySound( m_nHeySfxID );

				else if( XA->SFXIsSoundPlaying( m_nHeySfxID ) == true )
					XA->SFXStopSound( m_nHeySfxID );
			}
		}
		break;
	}
}

void CEnemy::StayInBoundaries( void )
{
	float fBLeft, fBTop, fBRight, fBBottom;

	fBLeft	 = (float)(GetWidth()* 0.5f);
	fBTop	 = (float)(GetHeight()* 0.5f);
	fBRight	 = (float)(1024 - (GetWidth()* 0.5f));
	fBBottom = (float)(1024 - (GetHeight() * 0.5f));

	if ( GetPosX() <= fBLeft )
	{
		SetPosX( fBLeft );
	}
	if ( GetPosY()	<= fBTop )
	{
		SetPosY( fBTop );
	}
	if ( GetPosX() >= fBRight )
	{
		SetPosX( fBRight );
	}
	if ( GetPosY() >= fBBottom )
	{	
		SetPosY( fBBottom );
	}
}